package file;

import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * This class pretends to be a PrintStream, but actually outputs to a list of PrintStreams. You can
 * set this to System.out and have it output to as many files/consoles as you want.
 * 
 * @author Kyle_Solo
 */
public class PrintStreamList extends PrintStream {

	private List<PrintStream> printStreamList = new ArrayList<PrintStream>();

	/**
	 * Creates a PrintStreamList, adding a PrintStream to it to initialize it.
	 * 
	 * @param first
	 */
	public PrintStreamList(PrintStream first) {
		super(first);
		printStreamList.add(first);
	}

	/**
	 * Adds a PrintStream to this list
	 * 
	 * @param printStream
	 */
	public void add(PrintStream printStream) {
		printStreamList.add(printStream);
	}

	@Override
	public PrintStream append(char c) {
		for (PrintStream p : printStreamList) {
			p.append(c);
		}
		return this;
	}

	@Override
	public PrintStream append(CharSequence csq) {
		for (PrintStream p : printStreamList) {
			p.append(csq);
		}
		return this;
	}

	@Override
	public PrintStream append(CharSequence csq, int start, int end) {
		for (PrintStream p : printStreamList) {
			p.append(csq, start, end);
		}
		return this;
	}

	@Override
	public boolean checkError() {
		throw new UnsupportedOperationException();
	}

	@Override
	protected void clearError() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void close() {
		for (PrintStream p : printStreamList) {
			p.close();
		}
	}

	@Override
	public void flush() {
		for (PrintStream p : printStreamList) {
			p.flush();
		}
	}

	@Override
	public PrintStream format(Locale l, String format, Object... args) {
		for (PrintStream p : printStreamList) {
			p.format(l, format, args);
		}
		return this;
	}

	@Override
	public PrintStream format(String format, Object... args) {
		for (PrintStream p : printStreamList) {
			p.format(format, args);
		}
		return this;
	}

	@Override
	public void print(boolean b) {
		for (PrintStream p : printStreamList) {
			p.print(b);
		}
	}

	@Override
	public void print(char c) {
		for (PrintStream p : printStreamList) {
			p.print(c);
		}
	}

	@Override
	public void print(char[] s) {
		for (PrintStream p : printStreamList) {
			p.print(s);
		}
	}

	@Override
	public void print(double d) {
		for (PrintStream p : printStreamList) {
			p.print(d);
		}
	}

	@Override
	public void print(float f) {
		for (PrintStream p : printStreamList) {
			p.print(f);
		}
	}

	@Override
	public void print(int i) {
		for (PrintStream p : printStreamList) {
			p.print(i);
		}
	}

	@Override
	public void print(long l) {
		for (PrintStream p : printStreamList) {
			p.print(l);
		}
	}

	@Override
	public void print(Object obj) {
		for (PrintStream p : printStreamList) {
			p.print(obj);
		}
	}

	@Override
	public void print(String s) {
		for (PrintStream p : printStreamList) {
			p.print(s);
		}
	}

	@Override
	public PrintStream printf(Locale l, String format, Object... args) {
		for (PrintStream p : printStreamList) {
			p.printf(l, format, args);
		}
		return this;
	}

	@Override
	public PrintStream printf(String format, Object... args) {
		for (PrintStream p : printStreamList) {
			p.printf(format, args);
		}
		return this;
	}

	@Override
	public void println() {
		for (PrintStream p : printStreamList) {
			p.println();
			p.flush();
		}
	}

	@Override
	public void println(boolean x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(char x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(char[] x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(double x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(float x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(int x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(long x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(Object x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	public void println(String x) {
		for (PrintStream p : printStreamList) {
			p.println(x);
			p.flush();
		}
	}

	@Override
	protected void setError() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void write(byte[] b) throws IOException {
		for (PrintStream p : printStreamList) {
			p.write(b);
		}
	}

	@Override
	public void write(byte[] buf, int off, int len) {
		for (PrintStream p : printStreamList) {
			p.write(buf, off, len);
		}
	}

	@Override
	public void write(int b) {
		for (PrintStream p : printStreamList) {
			p.write(b);
		}
	}
}
